package com.example.demo.service;

import com.example.demo.domain.receive.RewNewBookReceive;
import com.example.demo.domain.result.BookDetailResult;
import com.example.demo.domain.result.FindBookResult;
import com.example.demo.domain.result.ReNewBookResult;
import com.example.demo.domain.result.helper.FindBookInfo;
import com.example.demo.domain.result.helper.Book;
import com.example.demo.domain.result.CertificateInformationResult;
import com.example.demo.domain.result.helper.BookDetailInfo;
import com.example.demo.exception.ParamErrorException;
import com.example.demo.exception.PasswordErrorException;
import com.example.demo.utils.HbutLoginUtil;
import com.example.demo.utils.LogUtil;
import com.example.demo.utils.VerifyCodeUtil;
import com.google.gson.Gson;
import lombok.extern.slf4j.Slf4j;
import net.sourceforge.tess4j.TesseractException;
import org.apache.http.NameValuePair;
import org.apache.http.client.CookieStore;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.BasicCookieStore;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;
import org.jsoup.Connection;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
import org.springframework.stereotype.Service;

import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

import static org.jsoup.nodes.Document.OutputSettings.Syntax.html;

/**
 * 查询图书馆信息
 *
 * @author lizijian
 */
@Slf4j
@Service
public class LibraryService {
    private static final String USER_AGENT = "Mozilla/5.0 (Windows NT 6.1; WOW64; rv:29.0) Gecko/20100101 Firefox/29.0";
    private static final String FIND_BOOK_URL = "http://agentdockingopac.featurelib.libsou.com/showhome/searchlist/opacSearchList";
    private static final String LIBRARY_CARD_URL = "https://sso.hbut.edu.cn:7002/cas/login?service=http%3A%2F%2F202.114.181.8%3A8080%2Freader%2Fhwthau.php%3F_tsp_%3D1617113170007";
    private static final String LIBRARY_BOOK_URL = "http://202.114.181.8:8080/reader/book_lst.php";

    /**
     * 设置用户图书的信息
     */
    private static void setBookInfo(Elements args, CertificateInformationResult temp) {
        int i = 0;
        for (Element element : args) {
            Elements strong = element.select("strong");
            if (i == 0) {
                temp.setDueInFiveDaysSum(strong.html());
            } else if (i == 1) {
                temp.setExpiredSum(strong.html());
            } else if (i == 2) {
                temp.setAppointedSum(strong.html());
            } else if (i == 3) {
                temp.setEntrustedSum(strong.html());
            }
            i++;
        }

    }

    /**
     * 设置用户信息
     */
    private static void setUserInfo(Elements args, CertificateInformationResult temp) {
        int i = 0;
        for (Element trElement : args) {
            if (i != 0 && i != 3 && i != 4) {
                i++;
                continue;
            }
            int j = 0;
            Elements td = trElement.select("td");
            for (Element tdElement : td) {
                String tdHtml = tdElement.html();
                if (i == 0) {
                    if (j == 1) {
                        temp.setName(tdHtml.substring(tdHtml.lastIndexOf(">") + 1));
                    } else if (j == 2) {
                        temp.setIdNumber(tdHtml.substring(tdHtml.lastIndexOf(">") + 1));
                    } else if (j == 3) {
                        temp.setBarCode(tdHtml.substring(tdHtml.lastIndexOf(">") + 1));
                    }
                } else if (i == 3) {
                    if (j == 0) {
                        temp.setUserType(tdHtml.substring(tdHtml.lastIndexOf(">") + 1));
                    } else if (j == 1) {
                        temp.setGrade(tdHtml.substring(tdHtml.lastIndexOf(">") + 1));
                    } else if (j == 2) {
                        temp.setBorrowSum(tdHtml.substring(tdHtml.lastIndexOf(">") + 1));
                    }
                } else if (i == 4) {
                    if (j == 0) {
                        temp.setIllegalSum(tdHtml.substring(tdHtml.lastIndexOf(">") + 1));
                    } else if (j == 1) {
                        temp.setArrearsSum(tdHtml.substring(tdHtml.lastIndexOf(">") + 1));
                    }
                }
                j++;
            }
            i++;
        }
    }

    /**
     * 获取图书馆证件和借阅信息
     */
    public static CertificateInformationResult getLibraryInfo(String username, String password) throws IOException, PasswordErrorException {
        Map<String, String> cookie = HbutLoginUtil.loginSso(username, password);
        Connection.Response response = Jsoup.connect(LIBRARY_CARD_URL).cookies(cookie).timeout(10000).header("User-Agent",USER_AGENT).execute();
        Connection.Response response1 = Jsoup.connect(LIBRARY_BOOK_URL).cookies(response.cookies()).timeout(10000).header("User-Agent", USER_AGENT).execute();
        //解析图书馆用户信息部分
        Document libraryCard = response.parse();
        Element mainBox = libraryCard.getElementById("mainbox");
        Element myLibContent = mainBox.getElementById("mylib_content");
        Elements myLibMsg = myLibContent.getElementsByClass("mylib_msg");
        Elements a = myLibMsg.select("a");
        CertificateInformationResult certificateInformationResult = new CertificateInformationResult();
        setBookInfo(a, certificateInformationResult);
        Element myLibInfo = myLibContent.getElementById("mylib_info");
        Elements myLibInfoTr = myLibInfo.select("tr");
        setUserInfo(myLibInfoTr, certificateInformationResult);

        //解析图书馆借阅书籍部分
        Document libraryBook = response1.parse();
        //每一个tr代表一本书
        Elements tableLine = libraryBook.getElementsByClass("table_line");
        Elements tr = tableLine.select("tr");
        int sum = 0;
        for (Element element : tr) {
            if (sum == 0) {
                sum++;
                continue;
            }
            Book book = new Book();
            Elements td = element.select("td");
            int tdSum = 0;
            for (Element item : td) {
                if (tdSum == 0) {
                    book.setBarCode(item.html());
                } else if (tdSum == 1) {
                    book.setBookName(item.select("a").html());
                } else if (tdSum == 2) {
                    book.setBorrowDate(item.html());
                } else if (tdSum == 3) {
                    book.setReturnData(item.select("font").html());
                } else if (tdSum == 4) {
                    book.setRenewSum(item.html());
                } else if (tdSum == 5) {
                    book.setAddress(item.html());
                }
                tdSum++;
            }
            sum++;
            String[] onclicks = element.select("input").attr("onclick").split(",");
            if(onclicks.length>0){
                String onclick = onclicks[1];
                String check=onclick.substring(1,onclick.length()-1);
                book.setCheck(check);
            }
            certificateInformationResult.books.add(book);
        }
        return certificateInformationResult;
    }


    public void checkType(String type) throws ParamErrorException {
        if (!"title".equals(type) && !"author".equals(type) && !"subject".equals(type) && !"isbn".equals(type)) {
            throw new ParamErrorException("type 参数格式错误");
        }
    }


    public FindBookResult findBook(String type, String name,Integer page) throws IOException, ParamErrorException {
        checkType(type);
        if(page==null){
            page=1;
        }
        ArrayList<FindBookInfo> bookInfos = new ArrayList<>(50);
        Map<String, String> data = new HashMap<>(8);
        data.put("search", name);
        data.put("schoolId", "1245");
        data.put("searchtype", type);
        data.put("xc", "3");
        data.put("page",page+"");
        Connection.Response response = Jsoup.connect(FIND_BOOK_URL).data(data).timeout(8000).execute();
        Document document = response.parse();
        Elements books = document.select("li");
        for (Element book : books) {
            FindBookInfo findBookInfo = new FindBookInfo();
            Elements p = book.select("p");
            String info = p.get(0).html();
            info = info.substring(info.indexOf('：') + 1, info.indexOf('&'));
            findBookInfo.setInfo(info);
            String p2 = p.get(1).html();
            p2 = p2.substring(p2.indexOf('：') + 1);
            String total = p2.substring(p2.indexOf('：') + 1, p2.indexOf(" "));
            findBookInfo.setTotal(total);
            String available = p2.substring(p2.lastIndexOf('：') + 1);
            findBookInfo.setAvailable(available);
            String address = p.get(2).html();
            findBookInfo.setAddress(address.substring(address.indexOf('：') + 1));
            bookInfos.add(findBookInfo);
            String title = book.select("span").html();
            if(title.contains("<font")){
                title = title.replace(title.substring(title.indexOf("<"), title.lastIndexOf(">") + 1), name);
                title = title.substring(title.indexOf(".") + 1);
            }else {
                title=title.substring(title.indexOf('.')+1);
            }
            findBookInfo.setName(title);
            String url = "http://agentdockingopac.featurelib.libsou.com/" + book.select("a").attr("href");
            url = url.replace("&", "%26");
            findBookInfo.setUrl(url);
        }
        Elements option = document.select("option");
        String pageSum=null;
        if(option.size()>0){
            pageSum=option.get(0).html();
            pageSum=pageSum.substring(pageSum.indexOf('/')+1);
        }else {
            pageSum="1";
        }
        return new FindBookResult(Integer.parseInt(pageSum),bookInfos);
    }

    public BookDetailResult getBookDetail(String url) throws IOException {
        url = url.replace("%26", "&");
        BookDetailResult result = new BookDetailResult();
        Connection.Response response = Jsoup.connect(url).execute();
        Document document = response.parse();
        log.info(LogUtil.getMessage("body:" + document.body()));
        Elements p = document.getElementsByClass("catalog").select("p");
        for (Element item : p) {
            String html = item.html();
            if (html.contains("提要文摘附注")) {
                html = html.substring(html.lastIndexOf("&nbsp;") + 6);
                result.setDescription(html);
            }
            if (html.contains("使用对象附注")) {
                html = html.substring(html.lastIndexOf("&nbsp;") + 6);
                result.setObject(html);
            }
        }
        ArrayList<BookDetailInfo> bookDetailInfos = new ArrayList<>(5);
        result.setBookInfo(bookDetailInfos);
        Elements tableCon = document.getElementsByClass("tableCon");
        if ("".equals(tableCon.html())) {
            return result;
        }
        for (Element item : tableCon) {
            Elements tr = item.select("tr");
            BookDetailInfo bookDetailInfo = new BookDetailInfo();
            String barCode = tr.get(1).select("td").html();
            bookDetailInfo.setBarCode(barCode);
            String address = tr.get(2).select("td").html();
            address = address.substring(0, address.indexOf("&nbsp"));
            bookDetailInfo.setAddress(address);
            String state = tr.get(3).select("td").html();
            bookDetailInfo.setState(state);
            bookDetailInfos.add(bookDetailInfo);
        }
        return result;
    }
    public List<ReNewBookResult> renewBook(String username, String password, RewNewBookReceive[] rewNewBookReceives) throws IOException, PasswordErrorException, TesseractException {
        ArrayList<ReNewBookResult> results=new ArrayList<>(10);
        Map<String, String> cookie = HbutLoginUtil.loginSso(username, password);
        Connection.Response cardResponse = Jsoup.connect(LIBRARY_CARD_URL).cookies(cookie).timeout(10000).header("User-Agent",USER_AGENT).execute();
        String verifyCode = VerifyCodeUtil.getHbutVerifyCode(cardResponse.cookies());
        for (RewNewBookReceive rewNewBookReceive : rewNewBookReceives) {
            long time = System.currentTimeMillis();
            String renewUrl = "http://202.114.181.8:8080/reader/ajax_renew.php?bar_code=" + rewNewBookReceive.getBarCode()
                    + "&check=" + rewNewBookReceive.getCheck() + "&time=" + time + "&captcha=" + verifyCode;
            Connection.Response renewResponse = Jsoup.connect(renewUrl).cookies(cardResponse.cookies()).header("User-Agent",USER_AGENT).execute();
            log.info("result:" + renewResponse.body());
            String message = renewResponse.parse().select("font").html();
            results.add(new ReNewBookResult(rewNewBookReceive.getBarCode(),message));
        }
        return results;
    }

    public static void main(String[] args) throws ParamErrorException, IOException, PasswordErrorException, TesseractException {
        CertificateInformationResult libraryInfo = getLibraryInfo("2110300915", "12242211");
        System.out.println(libraryInfo);
    }


}
